
import screen.JXBMCRemote;
import screen.JXBMCKeyboard;
import screen.JXBMCConfigure;
import java.io.IOException;
import java.util.*;

import javax.microedition.lcdui.*;
import javax.microedition.media.control.VolumeControl;
import javax.microedition.midlet.*;
import controller.ButtonController;
import controller.ImageButton;
import controller.ScreenController;
import controller.VolumeController;

public class JXBMCMidlet extends MIDlet implements CommandListener {

    private Display display;
    private JXBMCConfigure form;
    private Displayable current;
    private Command quit, start;
    private Command keyboardSendCmd;
    private Command keyboardBackCmd;

    private RemoteCanvas remoteCanvas;
    private JXBMCRemote remote;
    private JXBMCKeyboard keyboard;

    public JXBMCMidlet() {
        form  = new JXBMCConfigure();
        quit  = new Command("Quit", Command.EXIT, 0);
        start = new Command("Start", Command.SCREEN, 0);
        form.addCommand(start);
        form.addCommand(quit);
        form.setCommandListener(this);

        keyboard = new JXBMCKeyboard();
        keyboardSendCmd = new Command("Send", Command.SCREEN, 0);
        keyboardBackCmd = new Command("Back", Command.BACK, 1);

        keyboard.addCommand(keyboardSendCmd);
        keyboard.addCommand(keyboardBackCmd);
        keyboard.setCommandListener(this);
        remote   = new JXBMCRemote();
    }

    public void startApp() {
        display = Display.getDisplay(this);
        if (current != null) {
            display.setCurrent(current);
        } else {
            display.setCurrent(form);
            current = form;
        }
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean b) {
    }

    public void commandAction(Command c, Displayable s) {
        if (c == quit) {
            notifyDestroyed();
            return;
        }

        if(c == keyboardSendCmd) {
            //System.err.println("Send key string:"+keyboard.getKeyboardString());
            String keypressed = keyboard.getKeyboardString();
            char keys[] = keypressed.toCharArray();
            try {
                for(int i=0; i<keys.length; i++) {
                    remote.keyChar(keys[i]);
                }
            } catch (Throwable ex) {
                ex.printStackTrace();
            }
        }

        form.store();
        if (remoteCanvas == null) {
            remoteCanvas = new RemoteCanvas(remote);
        }
        current = remoteCanvas;

        remote.init(form.getWebAddress(),
                form.getScreenHeight(),
                form.getScreenWidth());

        display.setCurrent(remoteCanvas);
    }

    class RemoteCanvas extends Canvas implements CommandListener {

        private JXBMCRemote remote;
        private Timer timer;
        private RefreshTask refreshTask;
        private final static int KEY_CODE_CLEAR = -8;
        private Command backCmd;
        private Command volumeCmd;
        private Command screenCmd;
        private Command keyboardCmd;
        private Command remoteCmd;
        private Command currentCmd;
        private Command shutdownCmd;

        private VolumeController volumeController;
        private ScreenController screenController;

        class RefreshTask extends TimerTask {

            public void run() {
                RemoteCanvas.this.repaint();
            }
        }

        RemoteCanvas(JXBMCRemote remoteVal) {
            backCmd = new Command("Back", Command.BACK, 0);
            remoteCmd = new Command("Remote", Command.SCREEN, 1);
            volumeCmd = new Command("Volume", Command.SCREEN, 2);
            screenCmd = new Command("Screen", Command.SCREEN, 2);
            keyboardCmd = new Command("KeyBoard", Command.SCREEN, 3);
            shutdownCmd = new Command("ShutDown", Command.SCREEN, 4);

            this.addCommand(backCmd);
            this.addCommand(remoteCmd);
            this.addCommand(volumeCmd);
            this.addCommand(screenCmd);
            this.addCommand(keyboardCmd);
            this.addCommand(shutdownCmd);

            this.setCommandListener(this);

            currentCmd = remoteCmd;

            remote = remoteVal;

            this.setFullScreenMode(true);
            timer = new Timer();
            refreshTask = new RefreshTask();
            timer.schedule(refreshTask, 50, 50);

            volumeController = new VolumeController(this.getWidth(),
                                                    this.getHeight());
            screenController = new ScreenController(this.getWidth(),
                                                    this.getHeight());
        }

        protected void paint(Graphics g) {
            int w = getWidth();
            int h = getHeight();
            g.setColor(244, 244, 244);
            g.fillRect(0, 0, w, h);
            g.setGrayScale(12 * 14);

            Image img = null;
            try {
                img = remote.refreshScreen();
            } catch (IOException e) {
                img = null;
            }
            if (img != null) {
                g.drawImage(img, 0, 0, Graphics.TOP | Graphics.LEFT);
            }
            if (currentCmd == volumeCmd) {
                volumeController.paint(g);
            } else {
                screenController.paint(g);
            }
        }

        protected void keyPressed(int keyCode) {
            String keyValue = this.getKeyName(keyCode);
            System.err.println("currCmd:"+currentCmd);
            try {
                if (currentCmd == volumeCmd) {
                    int gameAction = getGameAction(keyCode);
                    switch (gameAction) {
                        case UP:
                            volumeController.moveNext();
                            break;
                        case DOWN:
                            volumeController.movePrev();
                            break;
                        case FIRE:
                            int selected = volumeController.selected();
                            if (selected == VolumeController.BUTTON_ID_VOLUME_DOWN) {
                                remote.keyVolDown();
                            } else if (selected == VolumeController.BUTTON_ID_VOLUME_MUTE) {
                                remote.keyVolMute();
                            } else if (selected == VolumeController.BUTTON_ID_VOLUME_UP) {
                                remote.keyVolUp();
                            }
                            break;
                        case LEFT:
                        case RIGHT:
                        case GAME_A:
                        case GAME_B:
                        case GAME_C:
                        case GAME_D:
                        default:
                            break;
                    }
                } else if (currentCmd == screenCmd) {
                    int gameAction = getGameAction(keyCode);
                    switch (gameAction) {
                        case FIRE:
                            int selected = screenController.selected();
                            if (selected == ScreenController.BUTTON_ID_SCREEN_ZOOM_IN
                                || selected == ScreenController.BUTTON_ID_SCREEN_ZOOM_OUT) {
                                remote.zoom(screenController.getZoomValue());
                            } else if(selected == ScreenController.BUTTON_ID_SCREEN_ROTATE) {
                                remote.rotate();
                            } else if(selected == ScreenController.BUTTON_ID_SCREEN_MOVE_DOWN
                                    || selected == ScreenController.BUTTON_ID_SCREEN_MOVE_UP
                                    || selected == ScreenController.BUTTON_ID_SCREEN_MOVE_LEFT
                                    || selected == ScreenController.BUTTON_ID_SCREEN_MOVE_RIGHT) {
                                remote.move(screenController.getScreenPosX(),
                                            screenController.getScreenPosY());
                            }
                            break;
                        case LEFT:
                            screenController.moveNext();
                            break;
                        case RIGHT:
                            screenController.movePrev();
                            break;
                        case GAME_A:
                        case GAME_B:
                        case GAME_C:
                        case GAME_D:
                        case UP:
                        case DOWN:
                        default:
                            break;
                    }
                } else {
                    if (keyCode == KEY_CODE_CLEAR) {
                        remote.keyEsc();
                    } else {
                        int gameAction = getGameAction(keyCode);
                        keyValue = Integer.toString(keyCode);
                        switch (gameAction) {
                            case UP:
                                remote.keyLeft();
                                volumeController.moveNext();
                                break;
                            case DOWN:
                                remote.keyRight();
                                volumeController.movePrev();
                                break;
                            case LEFT:
                                remote.keyDown();
                                break;
                            case RIGHT:
                                remote.keyUp();
                                break;
                            case FIRE:
                                remote.keySelect();
                                break;
                            case GAME_A:
                            case GAME_B:
                            case GAME_C:
                            case GAME_D:
                            default:
                                break;
                        }
                    }
                }
            } catch (Throwable ex) {
                ex.printStackTrace();
            }
            repaint();
        }

        public void commandAction(Command c, Displayable d) {
            if (c == volumeCmd) {
                volumeController.setVisible(true);
            } else {
                volumeController.setVisible(false);
            }
            
            if (c == screenCmd) {
                screenController.setVisible(true);
            } else {
                screenController.setVisible(false);
            }

            if (c == backCmd) {
                current = form;
                display.setCurrent(form);
            }
            
            if (c == shutdownCmd) {
                try {
                    display.vibrate(10);
                    remote.shutDown();
                    JXBMCMidlet.this.notifyDestroyed();
                } catch (Throwable ex) {
                }
            }
            if (c == keyboardCmd) {
                System.err.println("keyboard.....");
                current = keyboard;
                display.setCurrent(keyboard);
            }

            currentCmd = c;
            System.err.println("current command:"+currentCmd);
        }
    }
}

